package cn.lysj.framework.coupon.util;

import cn.lysj.framework.common.utils.http.HttpUtil;
import cn.lysj.framework.common.utils.web.ParamUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/*
 * @author ZhangWenJian
 * @date 2019/1/25 16:18
 * @title :卡券分享链接工具类
 * @param null
 * @return
 * @description
 */

@Slf4j
public class JSSDKUtil {

	private static final String GET_WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token"; // get请求,获取公众号token,grant_type=client_credential
	private static final String GET_API_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; // get请求,获取jsapi_ticket

	private static String WX_ACCESS_TOKEN = "";// access_token
	private static Long WX_ACCESS_TOKEN_EXPIRES_IN = 0L;// access_token的有效期

	private static String JSAPI_TICKET = "";// jsapi_ticket
	private static Long JSAPI_TICKET_EXPIRES_IN = 0L;// jsapi_ticket的有效期



	private static final String wx_app_id = "wxce10ae5c4e042ccc"; //微信公众号APPID
	private static final String wx_app_secret = "fc608835ae9d965f2c64bafb5d14359c";// 微信公众号秘钥
    private static final String wx_grant_type = "client_credential";// 微信授权类型

	////////////////////////////////////////////////////////////
	private static final Type type = new TypeToken<Map<String, String>>() {
	}.getType();

	public static Map<String, String> getJS_SDK_Map(String url) {
		String jsapi_ticket = getJsApiTicket();
		return sign(jsapi_ticket, url);
	};

	public static Map<String, String> sign(String jsapi_ticket, String url) {
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = create_nonce_str();
		String timestamp = create_timestamp();
		String string1;
		String signature = "";

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		ret.put("url", url);
		ret.put("nonceStr", nonce_str);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);

		return ret;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	public static String getJsApiTicket() {
		if (JSAPI_TICKET_EXPIRES_IN > System.currentTimeMillis()) { // 还在有效期内
			return JSAPI_TICKET;
		} else { // 超过有效期限,重新获取
			StringBuilder sb = new StringBuilder();
			sb.append("access_token=").append(getAccessToken());
			sb.append("&type=jsapi");
			String ticketJson = HttpUtil.sendGet(GET_API_TICKET_URL, sb.toString());
//			System.out.println(ticketJson);
			Gson gson = new Gson();
			Map<String, String> map = gson.fromJson(ticketJson, type);
			String jsapi_ticket = map.get("ticket");
			if (ParamUtil.isBlank(jsapi_ticket)) {
				log.error("获取jsapi_ticket错误:" + ticketJson);
				return null;
			}
			JSAPI_TICKET = jsapi_ticket;
			JSAPI_TICKET_EXPIRES_IN = System.currentTimeMillis() + 7000 * 1000; // 官方时间7200秒,这里设置成7000秒
			return JSAPI_TICKET;
		}
	}

	public static String getAccessToken() {
		if (WX_ACCESS_TOKEN_EXPIRES_IN > System.currentTimeMillis()) { // 还在有效期内
			return WX_ACCESS_TOKEN;
		} else { // 超过有效期限,重新获取
			StringBuilder sb = new StringBuilder();
			sb.append("appid=").append(wx_app_id);
			sb.append("&secret=").append(wx_app_secret);
			sb.append("&grant_type=client_credential");
			String tokenJson = HttpUtil.sendGet(GET_WX_ACCESS_TOKEN_URL, sb.toString());
			// System.out.println(tokenJson);
			Gson gson = new Gson();
			Map<String, String> map = gson.fromJson(tokenJson, type);
			String accessToken = map.get("access_token");
			if (ParamUtil.isBlank(accessToken)) {
				log.error("获取Access_Token错误:" + tokenJson);
				return null;
			}
			WX_ACCESS_TOKEN = accessToken;
			WX_ACCESS_TOKEN_EXPIRES_IN = System.currentTimeMillis() + 7000 * 1000; // 官方时间7200秒,这里设置成7000秒
			return WX_ACCESS_TOKEN;
		}
	}

	private static String create_nonce_str() {
		return UUID.randomUUID().toString();
	}

	private static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}
}
